package com.yida.gwj.scene.expend.service.impl;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.validation.Validator;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.domain.R;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.bean.BeanUtils;
import com.yida.common.core.utils.bean.BeanValidators;
import com.yida.common.core.utils.poi.ExcelUtil;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfBusinessFlag;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.domain.GwjFinanceAccountDetail;
import com.yida.gwj.api.domain.GwjFinanceAccountMain;
import com.yida.gwj.api.service.RemoteGwjConfigService;
import com.yida.gwj.api.service.RemoteGwjFinanceService;
import com.yida.gwj.common.domain.GwjBaseBuild;
import com.yida.gwj.common.domain.GwjBaseBusinessNum;
import com.yida.gwj.common.domain.GwjBaseCommunity;
import com.yida.gwj.common.domain.GwjBaseHouse;
import com.yida.gwj.common.domain.GwjBaseOwner;
import com.yida.gwj.common.enums.GwjBusinessLogResult;
import com.yida.gwj.common.enums.GwjBusinessStatus;
import com.yida.gwj.common.enums.GwjCheckAccountStatus;
import com.yida.gwj.common.enums.GwjCheckAccountType;
import com.yida.gwj.common.service.IGwjBaseBuildService;
import com.yida.gwj.common.service.IGwjBaseBusinessNumService;
import com.yida.gwj.common.service.IGwjBaseCommunityService;
import com.yida.gwj.common.service.IGwjBaseHouseService;
import com.yida.gwj.common.service.IGwjBaseOwnerService;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusiness;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessBuild;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessCommunity;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessDetail;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessHouse;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessHouseAndOwner;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessLog;
import com.yida.gwj.scene.expend.domain.GwjSceneExpendBusinessOwner;
import com.yida.gwj.scene.expend.domain.enums.BusinessFlagEnum;
import com.yida.gwj.scene.expend.domain.request.GwjSceneExpendBusinessRequest;
import com.yida.gwj.scene.expend.domain.request.GwjSceneExpendHouseAndOwnerRequest;
import com.yida.gwj.scene.expend.domain.request.GwjSceneExpendShareEquallyMoneyRequest;
import com.yida.gwj.scene.expend.domain.request.GwjSceneExpendSubmitRequest;
import com.yida.gwj.scene.expend.service.GwjSceneExpendBusinessMainService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessBuildService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessCommunityService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessDetailService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessHouseService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessLogService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessOwnerService;
import com.yida.gwj.scene.expend.service.IGwjSceneExpendBusinessService;
import com.yida.system.api.domain.SysUser;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * @author hmh
 * @date 2023/08/14
 */
@Service
public class GwjSceneExpendBusinessMainServiceImpl implements GwjSceneExpendBusinessMainService {

    private final Logger log = LoggerFactory.getLogger(GwjSceneExpendBusinessMainServiceImpl.class);

    // 业务组 s
    @Autowired
    private IGwjSceneExpendBusinessService iGwjSceneExpendBusinessService;

    @Autowired
    private IGwjSceneExpendBusinessDetailService iGwjSceneExpendBusinessDetailService;

    @Autowired
    private IGwjSceneExpendBusinessLogService iGwjSceneExpendBusinessLogService;

    @Autowired
    private IGwjSceneExpendBusinessCommunityService iGwjSceneExpendBusinessCommunityService;

    @Autowired
    private IGwjSceneExpendBusinessBuildService iGwjSceneExpendBusinessBuildService;

    @Autowired
    private IGwjSceneExpendBusinessHouseService iGwjSceneExpendBusinessHouseService;

    @Autowired
    private IGwjSceneExpendBusinessOwnerService iGwjSceneExpendBusinessOwnerService;
    // e

    // 远程组 s
    @Autowired
    private RemoteGwjConfigService remoteGwjConfigService;

    @Autowired
    private RemoteGwjFinanceService remoteGwjFinanceService;
    // e

    // 基础组 s
    @Autowired
    private IGwjBaseBusinessNumService businessNumService;

    @Autowired
    private IGwjBaseCommunityService iGwjBaseCommunityService;

    @Autowired
    private IGwjBaseBuildService iGwjBaseBuildService;

    @Autowired
    private IGwjBaseHouseService iGwjBaseHouseService;

    @Autowired
    private IGwjBaseOwnerService iGwjBaseOwnerService;
    // e
    // 缴款面积类型 1:实测面积；2：预测面积
    private static final Integer[] depositSizeType = {1, 2};

    @Autowired
    protected SqlSessionFactory sqlSessionFactory;

    @Autowired
    protected Validator validator;

    /* 
     * 保存业务信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBusiness(GwjSceneExpendBusinessRequest gwjSceneExpendBusinessRequest) {
        checkRequest(gwjSceneExpendBusinessRequest, false);
        Long areaId = gwjSceneExpendBusinessRequest.getAreaId();
        // 获取操作人员信息
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        // 案例信息
        GwjSceneExpendBusiness gseb = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusiness();
        Integer ifInsert = processSaveBusiness(areaId, sysUser, gseb);
        if (ifInsert == -1) {
            throw new ServiceException("保存操作失败！");
        }
        Long bizId = gseb.getBizId();
        // 维修工程信息
        GwjSceneExpendBusinessDetail gsebd = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusinessDetail();
        processSaveBusinessDetail(areaId, sysUser, bizId, gsebd, ifInsert);
        // 保存项目相关信息 s
        // 项目信息
        Long bizCommunityId = processSaveBusinessCommunity(bizId, gwjSceneExpendBusinessRequest.getCommunityId(), sysUser);
        // 楼栋信息
        processSaveBusinessBuild(bizId, areaId, bizCommunityId, gwjSceneExpendBusinessRequest.getBuildCodes(), sysUser);
        // 新增房屋业主
        processSaveHouseAndOwnerByBuildCodes(bizId, areaId, gwjSceneExpendBusinessRequest.getBuildCodes(), sysUser);
        // e
        // 新增业务日志
        processSaveBusinessLog(gseb.getBizId(), gseb.getStepId(), "0", DateUtils.getNowDate(), null, sysUser);
        return true;
    }

    /**
     * 业务请求检测
     * 
     * @param gwjSceneExpendBusinessRequest 公维金请求类
     * @param isEdit 是否编辑
     */
    private void checkRequest(GwjSceneExpendBusinessRequest gwjSceneExpendBusinessRequest, boolean isEdit) {
        if (StringUtils.isNull(gwjSceneExpendBusinessRequest)) {
            throw new ServiceException("请求信息不能为空！");
        }
        GwjSceneExpendBusiness gseb = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusiness();
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("案例信息不能为空！");
        }

        if (isEdit && (StringUtils.isNull(gseb.getBizNum()) || StringUtils.isNull(gseb.getBizId()))) {
            throw new ServiceException("修改信息时，业务编号或者业务ID不能为空！");
        }
        // 看情况是否判定
        // if (StringUtils.isNull(gseb.getAcceptTime()) || StringUtils.isNull(gseb.getAcceptUserId()) ||
        // StringUtils.isNull(gseb.getAcceptUserName())) {
        // throw new ServiceException("受理人信息不能为空！");
        // }
        GwjSceneExpendBusinessDetail gsebd = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusinessDetail();
        if (StringUtils.isNull(gsebd)) {
            throw new ServiceException("维修工程信息不能为空！");
        }
        // 维修项目,维修原因,工程维修金额,实际分摊总金额,申报日期,拨款时间一,发票编号不能为空
        if (StringUtils.isNull(gsebd.getMaintenanceProject()) || StringUtils.isNull(gsebd.getMaintenanceReason()) || StringUtils.isNull(gsebd.getMaintenanceProjectApplicationTime()) || StringUtils.isNull(gsebd.getFirstAppropriationTime()) || StringUtils.isNull(gsebd.getInvoiceNum())) {
            throw new ServiceException("维修项目、维修原因、申报日期、,拨款时间一、发票编号不能为空！");
        }

    }

    /**
     * 案例信息保存处理
     * 
     * @param areaId 地区ID
     * @param sysUser 用户信息
     * @param gseb 案例信息
     * @param ifInsert 是否新增
     */
    private Integer processSaveBusiness(Long areaId, SysUser sysUser, GwjSceneExpendBusiness gseb) {
        Long userId = sysUser.getUserId();
        String realName = sysUser.getRealName();
        String bizNum = gseb.getBizNum();
        gseb.setUpdateId(userId);
        gseb.setUpdateBy(realName);
        if (StringUtils.isNull(bizNum)) {
            // 新建业务信息
            Long flagId = BusinessFlagEnum.SCENEEXPEND.getFlagId();
            GwjBaseBusinessNum gbbn = businessNumService.getNextNum(areaId, flagId.intValue());
            if (StringUtils.isNotNull(gbbn)) {
                // 业务编号
                bizNum = gbbn.toString();
            }
            gseb.setBizNum(bizNum);
            // 新增时候受理人为当前办理人员
            gseb.setAcceptUserId(userId);// 受理人ID
            gseb.setAcceptUserName(realName);// 受理人名称
            gseb.setAcceptTime(DateUtils.getNowDate());// 受理时间
            gseb.setCreateId(userId);
            gseb.setCreateBy(realName);
            gseb.setStatus("0");
            R<GwjConfBusinessFlag> gwjConfBusinessFlag = remoteGwjConfigService.selectGwjConfBusinessFlagByBizFlagId(flagId.intValue(), SecurityConstants.INNER);
            if (R.isError(gwjConfBusinessFlag)) {
                throw new ServiceException("获取业务流程信息失败！");
            }
            GwjConfBusinessFlag gcbf = gwjConfBusinessFlag.getData();
            if (StringUtils.isNull(gcbf)) {
                throw new ServiceException("业务信息未配置，请联系管理员！");
            }
            // 存储步骤ID
            R<List<GwjConfStep>> gwjConfSteps = remoteGwjConfigService.selectGwjConfStepListByFlagId(BusinessFlagEnum.SCENEEXPEND.getFlagId().intValue(), SecurityConstants.INNER);
            if (R.isError(gwjConfSteps)) {
                throw new ServiceException("获取步骤信息失败！");
            }
            List<GwjConfStep> list = gwjConfSteps.getData();
            if (StringUtils.isNull(list) || list.size() == 0) {
                throw new ServiceException("步骤信息未配置，请联系管理员！");
            }
            gseb.setBizFlagId(BusinessFlagEnum.SCENEEXPEND.getFlagId());
            gseb.setFlowId(gcbf.getFlowId());
            // 获取第一个步骤ID
            gseb.setStepId(list.get(0).getStepId());
            gseb.setAreaId(areaId);
            // 新增业务信息
            if (iGwjSceneExpendBusinessService.insertGwjSceneExpendBusiness(gseb) < 0) {
                throw new ServiceException("保存案例信息失败！");
            }
            return 1;
        }
        // 非空进行保存
        if (StringUtils.isNotNull(bizNum)) {
            checkBusinessOper(gseb, userId);
            if (iGwjSceneExpendBusinessService.updateGwjSceneExpendBusiness(gseb) < 0) {
                throw new ServiceException("修改案例信息失败！");
            }
            return 0;
        }
        return -1;
    }

    /**
     * 工程信息保存处理
     * 
     * @param areaId 地区ID
     * @param sysUser 用户信息
     * @param bizId 业务ID
     * @param gsebd 工程信息
     * @param ifInsert 是否新增
     */
    private void processSaveBusinessDetail(Long areaId, SysUser sysUser, Long bizId, GwjSceneExpendBusinessDetail gsebd, Integer ifInsert) {
        // Long userId = sysUser.getUserId();
        String realName = sysUser.getRealName();
        gsebd.setBizId(bizId);
        if (1 == ifInsert) {
            gsebd.setCreateBy(realName);
            iGwjSceneExpendBusinessDetailService.insertGwjSceneExpendBusinessDetail(gsebd);
        } else {
            gsebd.setUpdateBy(realName);
            iGwjSceneExpendBusinessDetailService.updateGwjSceneExpendBusinessDetail(gsebd);
        }

    }

    /**
     * 检查是否有权限操作
     * 
     * @param bizId 业务ID
     * @param userId 用户ID
     * @return
     */
    private boolean checkBusinessOper(Long bizId, Long userId) {
        GwjSceneExpendBusiness bsebVo = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        return checkBusinessOper(bsebVo, userId);
    }

    /**
     * 检查是否有权限操作
     * 
     * @param bizId 业务
     * @param userId 用户ID
     * @return
     */
    private boolean checkBusinessOper(GwjSceneExpendBusiness gseb, Long userId) {
        if (gseb.getUpdateId() != userId) {
            throw new ServiceException("当前人员无权限操作本业务！");
        }
        return true;
    }

    /**
     * 处理项目信息
     * 
     * @param bizId 业务ID
     * @param communityId 项目ID
     */
    private Long processSaveBusinessCommunity(Long bizId, Long communityId, SysUser sysUser) {
        if (communityId <= 0 || communityId == null) {
            throw new ServiceException("保存时项目ID不能为空！");
        }
        // 获取基础项目信息
        GwjBaseCommunity gbc = iGwjBaseCommunityService.selectGwjBaseCommunityByGwjBaseCommunityId(communityId);
        if (StringUtils.isNull(gbc)) {
            throw new ServiceException("未获取到对应项目信息，请核对后操作！");
        }
        GwjSceneExpendBusinessCommunity gsebc = new GwjSceneExpendBusinessCommunity();
        BeanUtils.copyBeanProp(gsebc, gbc);
        // 设置对应业务ID
        gsebc.setBizId(bizId);
        gsebc.setCreateBy(sysUser.getRealName());
        if (iGwjSceneExpendBusinessCommunityService.insertGwjSceneExpendBusinessCommunity(gsebc) < 0) {
            throw new ServiceException("项目新增失败！");
        }
        return gsebc.getBizCommunityId();
    }

    /**
     * 处理楼栋信息
     * 
     * @param bizId 业务ID
     * @param areaId 地区ID
     * @param bizCommunityId 业务项目ID
     * @param buildCodes 楼栋标识码
     */
    private void processSaveBusinessBuild(Long bizId, Long areaId, Long bizCommunityId, String[] buildCodes, SysUser sysUser) {
        if (StringUtils.isNull(buildCodes) || buildCodes.length == 0) {
            throw new ServiceException("保存时楼栋编号不能为空！");
        }
        List<GwjBaseBuild> list = iGwjBaseBuildService.selectGwjBaseBuildByBuildCodesAndAreaId(areaId, buildCodes);
        if (buildCodes.length != list.size()) {
            throw new ServiceException("查询楼栋数量不匹配，请核对楼栋数据！");
        }
        // 批量新增楼栋
        for (GwjBaseBuild gbb : list) {
            GwjSceneExpendBusinessBuild bsebb = new GwjSceneExpendBusinessBuild();
            BeanUtils.copyBeanProp(bsebb, gbb);
            // 设置bizId
            bsebb.setBizCommunityId(bizCommunityId);
            bsebb.setBizId(bizId);
            bsebb.setCreateBy(sysUser.getRealName());
            iGwjSceneExpendBusinessBuildService.insertGwjSceneExpendBusinessBuild(bsebb);
        }
    }

    /**
     * 处理房屋业主信息
     * 
     * @param bizId 业务ID
     * @param areaId 地区ID
     * @param buildCodes 楼栋标识码
     */
    private void processSaveHouseAndOwnerByBuildCodes(Long bizId, Long areaId, String[] buildCodes, SysUser sysUser) {
        if (StringUtils.isNull(buildCodes) || buildCodes.length == 0) {
            throw new ServiceException("保存时楼栋编号不能为空！");
        }
        List<String[]> buildCodesList = new ArrayList<String[]>();
        if (buildCodes.length > 10) {

            List<String> list = Arrays.asList(buildCodes);
            // 按10个进行分组
            List<List<String>> groupList = Lists.partition(list, 10);
            for (List<String> buildCodeList : groupList) {
                String[] buildCodeArray = (String[])buildCodeList.toArray();
                buildCodesList.add(buildCodeArray);
            }
        } else {
            buildCodesList.add(buildCodes);
        }
        String realName = sysUser.getRealName();
        // 分组查询房屋数据
        for (String[] buildCodeArray : buildCodesList) {
            List<GwjBaseHouse> houseList = iGwjBaseHouseService.selectGwjBaseListByBuildCodesAndAreaId(buildCodeArray, areaId);
            houseList.forEach(h -> h.setCreateBy(realName));
            // 新增房屋数据
            iGwjSceneExpendBusinessHouseService.insertBatchGwjSceneExpendBusinessHouseByBaseHouse(bizId, houseList);
            // 新增业主信息
            List<String> houseCodeList = houseList.stream().map(GwjBaseHouse::getHouseCode).collect(Collectors.toList());
            String[] houseCodeArray = new String[houseCodeList.size()];
            houseCodeArray = houseCodeList.toArray(houseCodeArray);
            // 查询对应房屋业务信息
            List<GwjBaseOwner> gboList = iGwjBaseOwnerService.selectGwjBaseListByGwjBaseHouseCodes(houseCodeArray, areaId);
            gboList.forEach(h -> h.setCreateBy(realName));
            iGwjSceneExpendBusinessOwnerService.insertBatchGwjSceneExpendBusinessOwner(bizId, gboList);
        }

    }

    /**
     * 业务日志
     * 
     * @param bizId 业务ID
     * @param setpId 步骤ID
     * @param result 操作结果 0:保存,1:提交,2:回退;3送件;4审核通过;5完结
     * @param acceptTime 当前处理时间
     * @param content 意见
     * @param operSysUser 操作员信息
     */
    private void processSaveBusinessLog(Long bizId, Long setpId, String result, Date acceptTime, String content, SysUser operSysUser) {
        GwjSceneExpendBusinessLog gwjSceneExpendBusinessLog = new GwjSceneExpendBusinessLog();
        gwjSceneExpendBusinessLog.setBizId(bizId);
        gwjSceneExpendBusinessLog.setStepId(setpId);
        gwjSceneExpendBusinessLog.setResult(result);
        gwjSceneExpendBusinessLog.setAcceptTime(acceptTime);
        gwjSceneExpendBusinessLog.setContent(content);
        gwjSceneExpendBusinessLog.setOperId(operSysUser.getUserId());
        gwjSceneExpendBusinessLog.setOperName(operSysUser.getRealName());
        gwjSceneExpendBusinessLog.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        if (iGwjSceneExpendBusinessLogService.insertGwjSceneExpendBusinessLog(gwjSceneExpendBusinessLog) < 0) {
            throw new ServiceException("业务日志新增失败！");
        }
    }

    /* 
     * 查询业务信息详情
     */
    @Override
    public JSONObject selectBusiness(Long bizId, Long areaId) {
        if (StringUtils.isNull(bizId) || StringUtils.isNull(areaId)) {
            throw new ServiceException("业务ID或地区ID不能为空！");
        }
        // 1获取业务信息
        GwjSceneExpendBusiness gwjSceneExpendBusiness = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        // 2获取业务详情信息
        GwjSceneExpendBusinessDetail gwjSceneExpendBusinessDetail = iGwjSceneExpendBusinessDetailService.selectGwjSceneExpendBusinessDetailByBizId(bizId);
        BigDecimal totalActualAllocationMoney = iGwjSceneExpendBusinessHouseService.selectActualAllocationMoneyTotalBybizIdAndAreaId(bizId, areaId);
        gwjSceneExpendBusinessDetail.setActualAllocationAmount(totalActualAllocationMoney);
        // 3获取项目信息
        List<GwjSceneExpendBusinessCommunity> gwjSceneExpendBusinessCommunityList = iGwjSceneExpendBusinessCommunityService.selectGwjSceneExpendBusinessCommunityList(new GwjSceneExpendBusinessCommunity() {
            /**
             *
             */
            private static final long serialVersionUID = -4240587730159192577L;
            {
                setBizId(bizId);
                setAreaId(areaId);
            }
        });
        // 4获取楼栋信息
        List<GwjSceneExpendBusinessBuild> gwjSceneExpendBusinessBuildList = iGwjSceneExpendBusinessBuildService.selectGwjSceneExpendBusinessBuildList(new GwjSceneExpendBusinessBuild() {
            /**
             *
             */
            private static final long serialVersionUID = 4042697851670203331L;
            {
                setBizId(bizId);
                setAreaId(areaId);
            }
        });
        JSONObject json = new JSONObject();
        json.put("gwjSceneExpendBusiness", gwjSceneExpendBusiness);
        json.put("gwjSceneExpendBusinessDetail", gwjSceneExpendBusinessDetail);
        json.put("gwjSceneExpendBusinessCommunityList", gwjSceneExpendBusinessCommunityList);
        json.put("gwjSceneExpendBusinessBuildList", gwjSceneExpendBusinessBuildList);
        return json;
    }

    /* 
     * 
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean editBusiness(GwjSceneExpendBusinessRequest gwjSceneExpendBusinessRequest) {
        checkRequest(gwjSceneExpendBusinessRequest, true);
        // Long areaId = gwjSceneExpendBusinessRequest.getAreaId();
        // 获取操作人员信息
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        // 案例信息
        GwjSceneExpendBusiness gseb = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusiness();
        checkGwjSceneExpendBusiness(gseb, false);
        // 查询步骤功能表，是否允许操作修改
        R<List<String>> rList = remoteGwjConfigService.selectGwjConfStepConfigInfoCodeListByBizFlagId(gseb.getStepId(), SecurityConstants.INNER);
        if (R.isError(rList)) {
            throw new ServiceException("获取步骤配置信息失败！");
        }
        if (StringUtils.isNull(rList.getData())) {
            throw new ServiceException("获取步骤配置信息失败！请配置后操作！");
        }
        List<String> list = rList.getData();
        if (!list.contains("save") && !list.contains("edit")) {
            throw new ServiceException("当前步骤不允许修改！");
        }
        Long areaId = gwjSceneExpendBusinessRequest.getAreaId();
        Integer ifInsert = processSaveBusiness(areaId, sysUser, gseb);
        if (ifInsert == -1) {
            throw new ServiceException("修改操作失败！");
        }
        Long bizId = gseb.getBizId();
        // 维修工程信息
        GwjSceneExpendBusinessDetail gsebd = gwjSceneExpendBusinessRequest.getGwjSceneExpendBusinessDetail();
        // 修改
        processSaveBusinessDetail(areaId, sysUser, bizId, gsebd, 0);
        // 修改基础房屋数据
        // Long bizId, Long areaId, Long communityId, String[] buildCodes, SysUser sysUser
        processEditBasicHouse(bizId, areaId, gwjSceneExpendBusinessRequest.getCommunityId(), gwjSceneExpendBusinessRequest.getBuildCodes(), sysUser);
        // 新增业务日志
        processSaveBusinessLog(gseb.getBizId(), gseb.getStepId(), "0", DateUtils.getNowDate(), null, sysUser);
        return true;
    }

    /* 
     * 业务信息提交
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    // public boolean submitBusiness(Long bizId, Long areaId, Long stepId) {
    public boolean submitBusiness(GwjSceneExpendSubmitRequest gsesr) {
        if (StringUtils.isNull(gsesr)) {
            throw new ServiceException("提交请求参数不能为空！");
        }
        Long bizId = gsesr.getBizId();
        Long areaId = gsesr.getAreaId();
        Long stepId = gsesr.getStepId();
        if (StringUtils.isNull(bizId) || StringUtils.isNull(areaId) || StringUtils.isNull(stepId)) {
            throw new ServiceException("业务ID、地区ID或步骤ID不能为空！");
        }
        // 业务信息查询
        // GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        // if (gseb.getAreaId() != areaId) {
        // throw new ServiceException("当前业务无法在此地区操作！");
        // }
        // SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        // if (gseb.getUpdateId() != sysUser.getUserId()) {
        // throw new ServiceException("非当前业务办理人员不能操作！");
        // }
        // 提交时候步骤会不一致
        GwjSceneExpendBusiness gseb = checkGwjSceneExpendBusiness(bizId, areaId, stepId, true);
        R<JSONArray> result = remoteGwjConfigService.getGwjConfStepConfigListInner(stepId, SecurityConstants.INNER);
        if (R.isError(result) || StringUtils.isNull(result.getData())) {
            throw new ServiceException("步骤配置信息获取失败！" + result.getMsg());
        }
        JSONArray jsonArray = result.getData();
        List<String> autoList = new ArrayList<String>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject j = jsonArray.getJSONObject(i);
            String code = j.getString("code");
            // 判定是否包含自动
            if (code.startsWith("auto")) {
                String autoCode = code.substring("auto_".length(), code.length());
                autoList.add(autoCode);
            }
            // 这里对财务对账做特殊检测
            if ("finance_check".equals(code)) {
                autoList.add(code);
            }
        }
        // 处理自动功能
        if (autoList.size() > 0) {
            processSubmitAuto(gseb, autoList);
        }
        // 修改步骤
        R<JSONObject> stepResult = remoteGwjConfigService.checkNextStepFinish(gseb.getBizFlagId().intValue(), stepId, SecurityConstants.INNER);
        if (R.isError(stepResult) || StringUtils.isNull(stepResult.getData())) {
            throw new ServiceException("步骤信息获取失败！" + stepResult.getMsg());
        }
        JSONObject json = stepResult.getData();
        // 完成情况需要对房屋数据进行金额扣除
        if (json.getBooleanValue("finishStatus")) {
            // 扣除房屋金额
            baseHouseCharging(bizId);
        }
        // 更新步骤ID
        GwjConfStep nextStep = json.getObject("nextStep", GwjConfStep.class);
        GwjSceneExpendBusiness upGseb = new GwjSceneExpendBusiness();
        upGseb.setBizId(bizId);
        upGseb.setAreaId(areaId);
        String resultLog = GwjBusinessLogResult.SUBMIT.getCode();
        // 默认提交，如果是最后一步则改为办结
        if (json.getBooleanValue("finishStatus")) {
            upGseb.setStatus(GwjBusinessStatus.FINISH.getCode());
            resultLog = GwjBusinessLogResult.FINISH.getCode();
        }
        upGseb.setStepId(nextStep.getStepId());
        // 根据传入的人员信息变更
        upGseb.setUpdateId(gsesr.getChangeOperationUserId());
        upGseb.setUpdateBy(gsesr.getChangeOperationUserRealName());
        // 更新
        iGwjSceneExpendBusinessService.updateGwjSceneExpendBusiness(upGseb);
        // 新增日志
        processSaveBusinessLog(gseb.getBizId(), gseb.getStepId(), resultLog, DateUtils.getNowDate(), gsesr.getContent(), SecurityUtils.getLoginUser().getSysUser());
        return true;
    }

    /* 
     * 业务回退处理
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean returnBusiness(GwjSceneExpendSubmitRequest gsesr) {
        if (StringUtils.isNull(gsesr)) {
            throw new ServiceException("提交请求参数不能为空！");
        }
        Long bizId = gsesr.getBizId();
        Long areaId = gsesr.getAreaId();
        Long stepId = gsesr.getStepId();
        if (StringUtils.isNull(bizId) || StringUtils.isNull(areaId) || StringUtils.isNull(stepId)) {
            throw new ServiceException("业务ID、地区ID或步骤ID不能为空！");
        }
        // 业务信息查询
        // GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        // if (StringUtils.isNull(gseb)) {
        // throw new ServiceException("未查询到指定业务信息！");
        // }
        // if (gseb.getAreaId() != areaId) {
        // throw new ServiceException("当前业务无法在此地区操作！");
        // }
        // SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        // if (gseb.getUpdateId() != sysUser.getUserId()) {
        // throw new ServiceException("非当前业务办理人员不能操作！");
        // }
        GwjSceneExpendBusiness gseb = checkGwjSceneExpendBusiness(bizId, areaId, stepId, true);
        R<JSONArray> result = remoteGwjConfigService.getGwjConfStepConfigListInner(stepId, SecurityConstants.INNER);
        if (R.isError(result) || StringUtils.isNull(result.getData())) {
            throw new ServiceException("步骤配置信息获取失败！" + result.getMsg());
        }
        JSONArray jsonArray = result.getData();
        List<String> autoList = new ArrayList<String>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject j = jsonArray.getJSONObject(i);
            String code = j.getString("code");
            // 判定是否包含自动
            if (code.startsWith("auto")) {
                String autoCode = code.substring("auto_".length(), code.length());
                autoList.add(autoCode);
            }
            // 特殊处理检测是否包含财务对账
            if ("finance_check".equals(code)) {
                autoList.add(code);
            }
        }
        // 处理自动功能
        if (autoList.size() > 0) {
            processReturnAuto(gseb, autoList);
        }
        // 回退获取上一步信息
        R<GwjConfStep> returnResult = remoteGwjConfigService.selectPreviousGwjConfStepByFlagId(gseb.getBizFlagId().intValue(), stepId, SecurityConstants.INNER);
        if (R.isError(returnResult)) {
            throw new ServiceException("步骤回退失败！" + returnResult.getMsg());
        }
        if (StringUtils.isNull(returnResult)) {
            throw new ServiceException("当前是第一步无法再回退");
        }
        Long returnStepId = returnResult.getData().getStepId();
        // 修改回退步骤
        iGwjSceneExpendBusinessService.updateGwjSceneExpendBusiness(new GwjSceneExpendBusiness() {
            /**
             *
             */
            private static final long serialVersionUID = 3905971234205482878L;

            {
                setBizId(bizId);
                setStepId(returnStepId);
                setStatus(GwjBusinessStatus.FALLBACK.getCode());
            }
        });
        // 新增回退日志
        processSaveBusinessLog(gseb.getBizId(), returnStepId, GwjBusinessLogResult.FALLBACK.getCode(), DateUtils.getNowDate(), gsesr.getContent(), SecurityUtils.getLoginUser().getSysUser());
        return true;
    }

    /**
     * 提交自动处理
     * 
     * @param autoList
     */
    private void processSubmitAuto(GwjSceneExpendBusiness gseb, List<String> autoList) {
        for (String autoCode : autoList) {
            if ("make_strem".equals(autoCode)) {
                // 坑爹生成流水
                autoMakeStrem(gseb);
            }
            if ("check_amount".equals(autoCode)) {
                // 检测金额
                checkAmount(gseb);
            }
            if ("check_owner".equals(autoCode)) {
                // 检测业主数据
                checkOwnerInfo(gseb);
            }
            if ("finance_check".equalsIgnoreCase(autoCode)) {
                // 检测财务对账状态
                checkFinanceStatus(gseb);
            }
        }
    }

    /**
     * 回退自动处理
     * 
     * @param autoList
     */
    private void processReturnAuto(GwjSceneExpendBusiness gseb, List<String> autoList) {
        for (String autoCode : autoList) {
            if ("make_strem".equals(autoCode)) {
                // 对应步骤内生成的财务流水进行清除。清除流水信息
                cleanStrem(gseb);
            }
            if ("finance_check".equals(autoCode)) {
                // 财务对账回退
                financeCheckReturn(gseb);
            }

        }
    }

    /**
     * 自动生成流水
     * 
     * @param bizId 业务ID
     * @param areaId 地区ID
     */
    private void autoMakeStrem(GwjSceneExpendBusiness gseb) {

        Long bizId = gseb.getBizId();
        Long areaId = gseb.getAreaId();
        GwjSceneExpendBusinessDetail gsebd = iGwjSceneExpendBusinessDetailService.selectGwjSceneExpendBusinessDetailByBizId(bizId);
        if (StringUtils.isNull(gsebd)) {
            throw new ServiceException("未获取到对应维修工程信息！");
        }

        // 设置总账参数
        GwjFinanceAccountMain accountMain = new GwjFinanceAccountMain();
        Long bizNum = Long.valueOf(gseb.getBizNum());
        Integer bizFlagId = gseb.getBizFlagId().intValue();
        accountMain.setBizId(bizId);
        accountMain.setBizNum(bizNum);
        accountMain.setBizFlagId(bizFlagId);
        accountMain.setAreaId(areaId);
        // 查询总账信息
        R<GwjFinanceAccountMain> financeMainResult = remoteGwjFinanceService.getGwjFinanceAccountMain(accountMain, SecurityConstants.INNER);
        if (R.isError(financeMainResult)) {
            throw new ServiceException("获取总账信息失败！请联系管理员");
        }
        if (StringUtils.isNotNull(financeMainResult.getData())) {
            // 已经存在流水则放弃生成
            return;
        }
        accountMain.setIncomeMoney(BigDecimal.ZERO);
        accountMain.setPayMoney(gsebd.getMaintenanceProjectAmount());// 项目维修金额
        Date dealTime = gsebd.getSecondAppropriationTime();
        if (StringUtils.isNull(dealTime)) {
            dealTime = gsebd.getFirstAppropriationTime();
        }
        accountMain.setDealTime(dealTime);
        accountMain.setCheckStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
        accountMain.setCheckType(GwjCheckAccountType.HANDWORK.getCode());
        accountMain.setCompanyName(gsebd.getMaintenanceProjectApplicationUnitName());
        accountMain.setProjectName(gsebd.getMaintenanceProject());
        // 获取金额统计数据
        Map<String, BigDecimal> map = iGwjSceneExpendBusinessHouseService.countHoustData(bizId, areaId, "1");
        accountMain.setTotalSize(map.get("total_deposit_size"));
        // 该业务没有选择银行
        accountMain.setBankId(0L);
        accountMain.setBankName("");
        accountMain.setBankAccountType("1");
        accountMain.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        // 服务调用新增总账
        R<Integer> rMain = remoteGwjFinanceService.insertGwjFinanceAccountMain(accountMain, SecurityConstants.INNER);
        if (R.isError(rMain)) {
            throw new ServiceException("新增总账流水失败" + rMain.getMsg());
        }
        // 设置分账参数
        // 获取分类账房屋数据
        List<GwjSceneExpendBusinessHouse> houseList = iGwjSceneExpendBusinessHouseService.selectGwjSceneExpendBusinessHouseList(new GwjSceneExpendBusinessHouse() {

            /**
             *
             */
            private static final long serialVersionUID = 1L;
            {
                setBizId(bizId);
                setAreaId(areaId);
                // 只查询选中房屋数据
                setSelectFlag("1");
            }
        });
        if (StringUtils.isEmpty(houseList)) {
            throw new ServiceException("未获取到房屋数据！");
        }
        ArrayList<GwjFinanceAccountDetail> financeAccountDetailList = new ArrayList<GwjFinanceAccountDetail>();
        // houseList.forEach(house -> {
        // GwjFinanceAccountDetail financeAccountDetail = new GwjFinanceAccountDetail();
        // financeAccountDetail.setIncomeMoney(BigDecimal.ZERO);
        // financeAccountDetail.setBizId(bizId);
        // financeAccountDetail.setBizNum(bizNum);
        // financeAccountDetail.setBizFlagId(bizFlagId);
        // financeAccountDetail.setHouseCode(house.getHouseCode());
        // financeAccountDetail.setPayMoney(house.getActualAllocationMoney());
        // financeAccountDetail.setAreaId(areaId);
        // financeAccountDetail.setCheckType(GwjCheckAccountType.HANDWORK.getCode());
        // financeAccountDetail.setCheckStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
        // //
        // financeAccountDetail.setBizFlagIdStr(GwjBusinessFlagType.getInfoByCode(maintenanceFundsBusiness.getBizFlagId()));
        // financeAccountDetail.setDealTime(dealTime);
        // financeAccountDetailList.add(financeAccountDetail);
        // });
        for (GwjSceneExpendBusinessHouse house : houseList) {
            GwjFinanceAccountDetail financeAccountDetail = new GwjFinanceAccountDetail();
            financeAccountDetail.setIncomeMoney(BigDecimal.ZERO);
            financeAccountDetail.setBizId(bizId);
            financeAccountDetail.setBizNum(bizNum);
            financeAccountDetail.setBizFlagId(bizFlagId);
            financeAccountDetail.setHouseCode(house.getHouseCode());
            financeAccountDetail.setPayMoney(house.getActualAllocationMoney());
            financeAccountDetail.setAreaId(areaId);
            financeAccountDetail.setCheckType(GwjCheckAccountType.HANDWORK.getCode());
            financeAccountDetail.setCheckStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
            // financeAccountDetail.setBizFlagIdStr(GwjBusinessFlagType.getInfoByCode(maintenanceFundsBusiness.getBizFlagId()));
            financeAccountDetail.setDealTime(dealTime);
            financeAccountDetailList.add(financeAccountDetail);
        }
        R<Integer> rDetail = remoteGwjFinanceService.insertBatchGwjFinanceAccountDetailInner(financeAccountDetailList, SecurityConstants.INNER);
        if (R.isError(rDetail)) {
            throw new ServiceException("新增分账流水失败" + rDetail.getMsg());
        }
    }

    /**
     * 金额检测
     * 
     * @param gseb
     */
    private void checkAmount(GwjSceneExpendBusiness gseb) {
        Long bizId = gseb.getBizId();
        // 从详情中获取对应的项目金额
        GwjSceneExpendBusinessDetail gsebd = iGwjSceneExpendBusinessDetailService.selectGwjSceneExpendBusinessDetailByBizId(bizId);
        if (StringUtils.isNull(gsebd)) {
            throw new ServiceException("未获取到对应业务详情数据");
        }
        // 获取工程预算金额
        BigDecimal maintenanceProjectAmount = gsebd.getMaintenanceProjectAmount();
        // 获取房屋统计数据
        Map<String, BigDecimal> countMap = iGwjSceneExpendBusinessHouseService.countHoustData(bizId, gseb.getAreaId(), "1");
        BigDecimal totalActualAllocationMoney = countMap.get("total_actual_allocation_money");
        if (maintenanceProjectAmount.compareTo(totalActualAllocationMoney) != 0) {
            throw new ServiceException("当前业务下实际分摊金额与预算金额不一致，请重新操作");
        }
    }

    /**
     * 业主信息检测
     * 
     * @param gseb
     */
    private void checkOwnerInfo(GwjSceneExpendBusiness gseb) {
        checkOwnerInfo(gseb.getBizId());
    }

    /**
     * 财务对账状态检测
     * 
     * @param gseb
     */
    private void checkFinanceStatus(GwjSceneExpendBusiness gseb) {

        // 获取财务对账状态
        // 设置总账参数
        GwjFinanceAccountMain accountMain = new GwjFinanceAccountMain();
        // 获取业务ID
        Long bizId = gseb.getBizId();
        Long bizNum = Long.valueOf(gseb.getBizNum());
        Integer bizFlagId = gseb.getBizFlagId().intValue();
        accountMain.setBizId(bizId);
        accountMain.setBizNum(bizNum);
        accountMain.setBizFlagId(bizFlagId);
        accountMain.setAreaId(gseb.getAreaId());
        // 查询总账信息
        R<GwjFinanceAccountMain> financeMainResult = remoteGwjFinanceService.getGwjFinanceAccountMain(accountMain, SecurityConstants.INNER);
        if (R.isError(financeMainResult)) {
            throw new ServiceException("获取总账信息失败！请联系管理员");
        }
        if (StringUtils.isNull(financeMainResult.getData())) {
            throw new ServiceException("未获取到对应的总账信息，请核对！");
        }
        // 获取对账状态
        String checkStatus = financeMainResult.getData().getCheckStatus();
        if ("0".equals(checkStatus)) {
            throw new ServiceException("未对账！请先进行财务对账后再操作！");
        }
    }

    /**
     * 清除流水
     * 
     * @param gseb 业务信息
     */
    private void cleanStrem(GwjSceneExpendBusiness gseb) {
        Long bizId = gseb.getBizId();
        // Long areaId = gseb.getAreaId();
        // 删除分类账信息
        R<Integer> detailResult = remoteGwjFinanceService.deleteGwjFinanceAccountDetailByBizId(bizId, SecurityConstants.INNER);
        if (R.isError(detailResult)) {
            throw new ServiceException("清除分类账流水失败！");
        }
        // 删除总账流水
        R<Integer> mainResult = remoteGwjFinanceService.deleteGwjFinanceAccountMainByBizId(bizId, SecurityConstants.INNER);
        if (R.isError(mainResult)) {
            throw new ServiceException("清除总账流水失败！");
        }
    }

    /* 
     * 财务对账
     */
    @Override
    public boolean financeCheck(Long bizId, Long areaId) {
        // 1查询业务信息
        GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("未获取到对应业务信息，请核对！");
        }
        financeCheck(gseb);
        return true;
    }

    /**
     * 财务对账提交
     * 
     * @param bizId
     */
    private void financeCheck(GwjSceneExpendBusiness gseb) {
        Long bizId = gseb.getBizId();
        Long areaId = gseb.getAreaId();
        Integer flagId = gseb.getBizFlagId().intValue();
        Date nowDate = DateUtils.getNowDate();
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        // 获取分类账统计信息
        GwjFinanceAccountDetail gfad = new GwjFinanceAccountDetail();
        gfad.setBizId(bizId);
        gfad.setAreaId(areaId);
        gfad.setBizFlagId(flagId);
        R<Map<String, BigDecimal>> detailResult = remoteGwjFinanceService.selectGwjFinanceAccountDetailStatistics(gfad, SecurityConstants.INNER);
        if (R.isError(detailResult) || StringUtils.isEmpty(detailResult.getData())) {
            throw new ServiceException("获取分类账统计数据失败！");
        }
        // 查询财务流水
        GwjFinanceAccountMain gfam = new GwjFinanceAccountMain();
        gfam.setBizId(bizId);
        gfam.setAreaId(areaId);
        gfam.setBizFlagId(flagId);
        R<GwjFinanceAccountMain> gfamResult = remoteGwjFinanceService.getGwjFinanceAccountMain(gfam, SecurityConstants.INNER);
        if (R.isError(gfamResult) || StringUtils.isNull(gfamResult.getData())) {
            throw new ServiceException("获取总账数据失败！");
        }
        // 总账支出金额
        BigDecimal mainPayMoney = gfamResult.getData().getPayMoney();
        // 分类账支出统计金额
        BigDecimal detailTotalPayMoney = detailResult.getData().get("total_pay_money");
        if (mainPayMoney.compareTo(detailTotalPayMoney) != 0) {
            throw new ServiceException("总账金额与分类账统计金额不一致，请重新生成流水！");
        }
        // 获取已选中房屋实际分摊金额
        Map<String, BigDecimal> statisticsMap = iGwjSceneExpendBusinessHouseService.countHoustData(bizId, areaId, "1");
        BigDecimal totalActualAllocationMoney = statisticsMap.get("total_actual_allocation_money");
        if (mainPayMoney.compareTo(totalActualAllocationMoney) != 0) {
            throw new ServiceException("总账金额与实际分摊金额不一致，请重新计算！");
        }
        // 全通过后修改财务对账状态和时间
        // 批量修改分类账
        GwjFinanceAccountDetail upGfad = new GwjFinanceAccountDetail();
        upGfad.setBizId(bizId);
        upGfad.setAreaId(areaId);
        upGfad.setBizFlagId(flagId);
        upGfad.setCheckStatus(GwjCheckAccountStatus.CHECK_SUCCESS.getCode());
        upGfad.setCheckTime(nowDate);
        upGfad.setUpdateBy(sysUser.getRealName());
        R<Integer> upDetailResult = remoteGwjFinanceService.updateGwjFinanceAccountDetail(upGfad, SecurityConstants.INNER);
        if (R.isError(upDetailResult) || upDetailResult.getData() < 1) {
            throw new ServiceException("分类账修改对账状态失败！");
        }
        // 总账状态修改
        gfam.setCheckStatus(GwjCheckAccountStatus.CHECK_SUCCESS.getCode());
        gfam.setCheckTime(nowDate);
        gfam.setUpdateBy(sysUser.getRealName());
        // 修改总账对账状态
        R<Integer> upMainResult = remoteGwjFinanceService.updateGwjFinanceAccountMainInfo(gfam, SecurityConstants.INNER);
        if (R.isError(upMainResult) || upMainResult.getData() < 1) {
            throw new ServiceException("总账修改对账状态失败！");
        }
        // 新增日志
        processSaveBusinessLog(gseb.getBizId(), gseb.getStepId(), GwjBusinessLogResult.SUBMIT.getCode(), DateUtils.getNowDate(), "", sysUser);
    }

    /**
     * 财务对账回退
     * 
     * @param gseb
     */
    private void financeCheckReturn(GwjSceneExpendBusiness gseb) {
        Long bizId = gseb.getBizId();
        Long areaId = gseb.getAreaId();
        Long bizNum = Long.getLong(gseb.getBizNum());
        Integer flagId = gseb.getBizFlagId().intValue();
        GwjFinanceAccountDetail gfad = new GwjFinanceAccountDetail();
        gfad.setBizId(bizId);
        gfad.setAreaId(areaId);
        gfad.setBizNum(bizNum);
        gfad.setBizFlagId(flagId);
        // 修改对账状态
        gfad.setCheckStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
        // 修改分账数据
        R<Integer> detailResult = remoteGwjFinanceService.updateGwjFinanceAccountDetail(gfad, SecurityConstants.INNER);
        if (R.isError(detailResult)) {
            throw new ServiceException("分类账流水状态修改失败！");
        }
        GwjFinanceAccountMain gfam = new GwjFinanceAccountMain();
        gfam.setBizId(bizId);
        gfam.setAreaId(areaId);
        gfam.setBizNum(bizNum);
        gfam.setBizFlagId(flagId);
        // 修改对账状态
        gfam.setCheckStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
        // 修改总账数据
        R<Integer> mainResult = remoteGwjFinanceService.updateGwjFinanceAccountMain(gfam, SecurityConstants.INNER);
        if (R.isError(mainResult)) {
            throw new ServiceException("总账流水状态修改失败！");
        }
        // 修改业务信息对账状态
        GwjSceneExpendBusiness upGseb = new GwjSceneExpendBusiness();
        upGseb.setBizId(bizId);
        upGseb.setAreaId(areaId);
        upGseb.setFinanceCheck(GwjCheckAccountStatus.NOT_CHECK.getCode());
        iGwjSceneExpendBusinessService.updateGwjSceneExpendBusinessByBizIdAndAreaId(upGseb);
    }

    /**
     * 20230818
     * 
     * hmh
     * 
     * 
     * 基础房屋扣费（案例完结）
     * 
     * 从内网支出那边搬过来的
     *
     * @param bizId 业务主键
     * @return
     */
    public Boolean baseHouseCharging(Long bizId) {
        if (StringUtils.isNull(bizId)) {
            throw new ServiceException("房屋扣费，业务ID不能为空！");
        }
        // 查询业务房屋信息
        List<GwjSceneExpendBusinessHouse> gwjSceneExpendBusinessHouseList = iGwjSceneExpendBusinessHouseService.selectGwjSceneExpendBusinessHouseList(new GwjSceneExpendBusinessHouse() {
            /**
             *
             */
            private static final long serialVersionUID = -3640257094171601897L;

            {
                setBizId(bizId);
                // 查询选中状态房屋
                setSelectFlag("1");
            }
        });
        // 判断业务房屋数据是否为空
        if (ObjectUtil.isEmpty(gwjSceneExpendBusinessHouseList)) {
            throw new ServiceException("基础房屋扣费失败，未查询到对应业务房屋信息");
        }
        // 业务房屋信息实际扣款金额转Map
        Map<Long, BigDecimal> actualAllocationMoneyMap = gwjSceneExpendBusinessHouseList.stream().collect(Collectors.toMap(GwjSceneExpendBusinessHouse::getHouseId, GwjSceneExpendBusinessHouse::getActualAllocationMoney));
        // 将业务房屋信息转换为基础房屋主键
        Long[] houseIds = gwjSceneExpendBusinessHouseList.stream().map(GwjSceneExpendBusinessHouse::getHouseId).toArray(Long[]::new);
        // 查询基础房屋信息
        List<GwjBaseHouse> baseHouses = iGwjBaseHouseService.selectGwjBaseHoseByHouseIds(houseIds);
        // 判断基础房屋数据是否为空
        if (ObjectUtil.isEmpty(baseHouses)) {
            throw new ServiceException("基础房屋扣费失败，未查询到对应基础房屋信息");
        }
        // 扣除基础房屋款项
        baseHouses = baseHouses.stream().map(item -> {
            // 判断房屋余额是否为空
            if (ObjectUtil.isEmpty(item.getCurrentMoney())) {
                throw new ServiceException("房屋编号为" + item.getHouseCode() + "可用余额为空");
            }
            // 计算房屋可用余额
            BigDecimal useableCurrentMoney = item.getCurrentMoney().subtract(ObjectUtil.isEmpty(item.getBlockedMoney()) ? BigDecimal.ZERO : item.getBlockedMoney());
            // 判断房屋可用余额是否大于零
            if (useableCurrentMoney.compareTo(BigDecimal.ZERO) < 0) {
                throw new ServiceException("房屋编号为" + item.getHouseCode() + "可用余额不足");
            }
            // 获取扣款金额
            BigDecimal actualAllocationMoney = actualAllocationMoneyMap.get(item.getHouseId());
            // 判断扣款金额是否为空
            if (ObjectUtil.isNotEmpty(actualAllocationMoney)) {
                // 判断房屋可用余额是否小于于扣款金额
                if (useableCurrentMoney.compareTo(actualAllocationMoney) < 0) {
                    throw new ServiceException("房屋编号为" + item.getHouseCode() + "可用余额不足,房屋可用余额小于业务扣款金额");
                }
                // 房屋可用余额扣除扣款金额并且加上冻结金额
                BigDecimal newCurrentMoney = useableCurrentMoney.subtract(actualAllocationMoney).add(item.getBlockedMoney());
                // 赋值基础房屋当前余额
                item.setCurrentMoney(newCurrentMoney);
            }
            return item;
        }).collect(Collectors.toList());
        // 更新业务基础房屋信息
        if (0 >= iGwjBaseHouseService.updateBatchGwjBaseHouse(baseHouses)) {
            throw new ServiceException("基础房屋扣费更新异常");
        }
        return Boolean.TRUE;
    }

    /**
     * 业务信息检测
     * 
     * @param requestGseb 业务信息请类
     * @param ifSubmit 是否验证步骤
     * @return
     */
    private GwjSceneExpendBusiness checkGwjSceneExpendBusiness(GwjSceneExpendBusiness requestGseb, boolean checkStep) {
        // 业务信息查询
        return checkGwjSceneExpendBusiness(requestGseb.getBizId(), requestGseb.getAreaId(), requestGseb.getStepId(), checkStep);
    }

    private void checkGwjSceneExpendBusiness(GwjSceneExpendBusiness gseb, Long areaId) {
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("未查询到指定业务信息！");
        }
        if (gseb.getAreaId() != areaId) {
            throw new ServiceException("当前业务无法在此地区操作！");
        }
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        if (gseb.getUpdateId() != sysUser.getUserId()) {
            throw new ServiceException("非当前业务办理人员不能操作！");
        }
    }

    private void checkGwjSceneExpendBusiness(GwjSceneExpendBusiness gseb, String[] areaIds) {
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("未查询到指定业务信息！");
        }
        // if (gseb.getAreaId() != areaId) {
        // 不包含地区时候进行提交
        if (!StringUtils.inStringIgnoreCase(gseb.getAreaId().toString(), areaIds)) {
            throw new ServiceException("当前业务无法在此地区操作！");
        }
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        if (gseb.getUpdateId() != sysUser.getUserId()) {
            throw new ServiceException("非当前业务办理人员不能操作！");
        }
    }

    private void checkGwjSceneExpendBusiness(GwjSceneExpendBusiness gseb, SysUser sysUser, String[] areaIds, Long stepId, boolean checkStep) {
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("未查询到指定业务信息！");
        }
        // if (gseb.getAreaId() != areaId) {
        // 不包含地区时候进行提交
        if (!StringUtils.inStringIgnoreCase(gseb.getAreaId().toString(), areaIds)) {
            throw new ServiceException("当前业务无法在此地区操作！");
        }
        if (gseb.getUpdateId() != sysUser.getUserId()) {
            throw new ServiceException("非当前业务办理人员不能操作！");
        }
        if (checkStep && (gseb.getStepId() != stepId)) {
            throw new ServiceException("当前办理业务步骤不一致！");
        }
    }

    private GwjSceneExpendBusiness checkGwjSceneExpendBusiness(Long bizId, Long areaId, Long stepId, boolean checkStep) {
        GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        if (StringUtils.isNull(gseb)) {
            throw new ServiceException("未查询到指定业务信息！");
        }
        if (gseb.getAreaId() != areaId) {
            throw new ServiceException("当前业务无法在此地区操作！");
        }
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        if (gseb.getUpdateId() != sysUser.getUserId()) {
            throw new ServiceException("非当前业务办理人员不能操作！");
        }
        if (checkStep && (gseb.getStepId() != stepId)) {
            throw new ServiceException("当前办理业务步骤不一致！");
        }
        return gseb;
    }

    /**
     * 按计算标准分摊金额
     * 
     * @param gsesemr 计算标准请求类
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean shareEquallyMoney(GwjSceneExpendShareEquallyMoneyRequest gsesemr) {
        Long bizId = gsesemr.getBizId();
        // 获取操作人员信息
        // SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        // 通过登录用户的地区信息判断
        checkGwjSceneExpendBusiness(gseb, SecurityUtils.getLoginUser().getAreaIds().split(","));
        // 获取分摊类型
        Integer standardType = gsesemr.getStandardType();
        processHouseShareEquallyMoney(gseb, standardType);
        return true;
    }

    /**
     * 处理房屋分摊金额
     * 
     * @param gseb 业务信息
     * @param standardType 分摊类型 1:按现房面积平摊 2:按期房面积平摊 3:按户平摊
     */
    private void processHouseShareEquallyMoney(GwjSceneExpendBusiness gseb, Integer standardType) {
        Long bizId = gseb.getBizId();
        String realName = SecurityUtils.getLoginUser().getSysUser().getRealName();
        List<GwjSceneExpendBusinessHouse> houseList = iGwjSceneExpendBusinessHouseService.selectGwjSceneExpendBusinessHouseList(new GwjSceneExpendBusinessHouse() {
            /**
             *
             */
            private static final long serialVersionUID = 5778012834085390866L;

            {
                setBizId(bizId);
                setSelectFlag("1");
            }
        });
        if (StringUtils.isEmpty(houseList)) {
            throw new ServiceException("未获取到对应房屋数据");
        }
        // 获取房屋统计信息
        Map<String, BigDecimal> countMap = iGwjSceneExpendBusinessHouseService.countHoustData(bizId, gseb.getAreaId(), "1");
        // 总面积
        BigDecimal totalSize = countMap.get("total_size");
        // 选中房屋总户数
        BigDecimal totalOwner = countMap.get("total_owner");
        // 获取预算金额
        GwjSceneExpendBusinessDetail gsebd = iGwjSceneExpendBusinessDetailService.selectGwjSceneExpendBusinessDetailByBizId(bizId);
        // 项目维修金额
        BigDecimal maintenanceProjectAmount = gsebd.getMaintenanceProjectAmount();
        // 提示信息
        StringBuffer sb = new StringBuffer();
        houseList.forEach(house -> {
            house.setLackMoney(BigDecimal.ZERO);
            house.setSelfRaiseMoney(BigDecimal.ZERO);
            BigDecimal allocationMoney = BigDecimal.ZERO;
            // 缴款面积
            BigDecimal depositSize = BigDecimal.ZERO;
            // 按面积计算公式:(房屋面积/总面积)*分摊金额,截取小数点后两位,剩下的进行补差额
            // if (ObjectUtil.equal(StandardTypeEnum.AREA.getCode(), shareEquallyMoneyRequest.getStandardType())) {
            // if (NumberUtil.equals(maintenanceFundsBusinessInfo.getTotalInvolvedArea(), BigDecimal.ZERO)) {
            // throw new
            // ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.ALLOCATED_AMOUNT_SELECT) +
            // "涉及总面积不能为0");
            // }
            // allocationMoney = NumberUtil.mul(NumberUtil.div(ObjectUtil.equal(house.getActualSize(), BigDecimal.ZERO)
            // ? house.getForecastSize() : house.getActualSize(), maintenanceFundsBusinessInfo.getTotalInvolvedArea()),
            // maintenanceFundsBusinessInfo.getProjectBudgetAmount());
            // house.setAllocationMoney(allocationMoney);
            // }
            // 20230717
            // 实测面积（现房）
            BigDecimal actualSize = StringUtils.isNull(house.getActualSize()) ? BigDecimal.ZERO : house.getActualSize();
            // 预测面积（期房）
            BigDecimal forecastSize = StringUtils.isNull(house.getForecastSize()) ? BigDecimal.ZERO : house.getForecastSize();
            // 非公用户进行中断
            if ("1".equals(house.getPublicFlag())) {
                throw new ServiceException("房屋编号：" + house.getHouseCode() + "属于公用户房屋，无法通过面积计算！");
            }
            if (BigDecimal.ZERO.compareTo(actualSize) == 0 && BigDecimal.ZERO.compareTo(forecastSize) == 0) {
                throw new ServiceException("房屋编号：" + house.getHouseCode() + "现房面积和期房面积均为空，无法计算！");
            }
            if (ArrayUtils.contains(depositSizeType, standardType)) {
                // 按实际面积取值(实测面积)
                if (1 == standardType) {
                    // depositSize = StringUtils.isNull(house.getActualSize()) ? BigDecimal.ZERO :
                    // house.getActualSize();
                    // 优先判断现房面积
                    depositSize = BigDecimal.ZERO.compareTo(actualSize) == 0 ? forecastSize : actualSize;
                }
                // 按预期面积取值(预测面积)
                if (2 == standardType) {

                    // depositSize = StringUtils.isNull(house.getForecastSize()) ? BigDecimal.ZERO :
                    // house.getForecastSize();
                    // 优先判断期房面积
                    depositSize = BigDecimal.ZERO.compareTo(forecastSize) == 0 ? actualSize : forecastSize;
                }
                allocationMoney = NumberUtil.mul(NumberUtil.div(depositSize, totalSize), maintenanceProjectAmount);
                house.setAllocationMoney(allocationMoney);

            }
            // 按户数计算公式:分摊金额/户数,截取小数点后两位,剩下的进行补差额
            if (ObjectUtil.equal(3, standardType)) {
                allocationMoney = NumberUtil.div(maintenanceProjectAmount, totalOwner, 2, RoundingMode.HALF_UP);
                house.setAllocationMoney(allocationMoney);
                // 按户优先现房
                depositSize = BigDecimal.ZERO.compareTo(actualSize) == 0 ? forecastSize : actualSize;
            }
            // 设置缴款面积
            allocationMoney.setScale(2, RoundingMode.HALF_UP);
            house.setDepositSize(depositSize);
            house.setTotalAllocationMoney(allocationMoney);
            house.setActualAllocationMoney(allocationMoney);
            house.setUpdateBy(realName);
            // 20230726 判断余额是否不足,余额小于实际分摊金额进行提示
            BigDecimal currentMoney = house.getCurrentMoney();
            if (currentMoney.compareTo(allocationMoney) == -1) {
                sb.append("房屋编号：").append(house.getHouseCode()).append("，实际分摊金额[").append(house.getActualAllocationMoney()).append("]").append("大于可用余额[").append(currentMoney).append("]").append("\n\r");
            }
        });
        // 20230726 查询是否存在提示信息
        if (StringUtils.isNotEmpty(sb) || sb.length() > 0) {
            throw new ServiceException(sb.toString());
        }
        // 做统一修改
        // 分批
        batch(houseList);
        // iGwjSceneExpendBusinessHouseService.upBatchGwjSceneExpendBusinessHouseByBaseHouse(houseList);
    }

    /**
     * 20230821
     * 
     * 根据业务ID查询房屋类型
     * 
     * @return
     */
    @Override
    public List<String> selectHouseUseType(Long bizId) {
        return iGwjSceneExpendBusinessHouseService.selectHouseUseType(bizId);
    }

    /* 
     * 检查业主信息
     */
    @Override
    public boolean checkOwnerInfo(Long bizId) {
        return iGwjSceneExpendBusinessHouseService.checkOwnerInfo(bizId);
    }

    /* 
     * 变更操作员
     */
    @Override
    public boolean changeOper(GwjSceneExpendSubmitRequest gwjSceneExpendSubmitRequest) {
        if (StringUtils.isNull(gwjSceneExpendSubmitRequest)) {
            throw new ServiceException("请求参数不能为空！");
        }
        if (StringUtils.isNull(gwjSceneExpendSubmitRequest.getBizId()) || StringUtils.isNull(gwjSceneExpendSubmitRequest.getChangeOperationUserId()) || StringUtils.isNull(gwjSceneExpendSubmitRequest.getChangeOperationUserRealName())) {
            throw new ServiceException("送件时，业务ID，接收人员ID和姓名不能为空！");
        }
        // 获取操作员信息
        // 获取操作人员信息
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        checkBusinessOper(gwjSceneExpendSubmitRequest.getBizId(), sysUser.getUserId());
        GwjSceneExpendBusiness gwjSceneExpendBusiness = new GwjSceneExpendBusiness();
        gwjSceneExpendBusiness.setBizId(gwjSceneExpendSubmitRequest.getBizId());
        gwjSceneExpendBusiness.setUpdateId(gwjSceneExpendSubmitRequest.getChangeOperationUserId());
        gwjSceneExpendBusiness.setUpdateBy(gwjSceneExpendSubmitRequest.getChangeOperationUserRealName());
        gwjSceneExpendBusiness.setUpdateTime(DateUtils.getNowDate());
        return iGwjSceneExpendBusinessService.updateGwjSceneExpendBusiness(gwjSceneExpendBusiness) > 0;
    }

    /* 
     * 签署意见
     */
    @Override
    public boolean signContent(GwjSceneExpendSubmitRequest gwjSceneExpendSubmitRequest) {
        if (StringUtils.isNull(gwjSceneExpendSubmitRequest)) {
            throw new ServiceException("请求参数不能为空！");
        }
        if (StringUtils.isNull(gwjSceneExpendSubmitRequest.getBizId())) {
            throw new ServiceException("签署意见业务ID不能为空！");
        }
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(gwjSceneExpendSubmitRequest.getBizId());
        checkBusinessOper(gseb, sysUser.getUserId());
        processSaveBusinessLog(gseb.getBizId(), gseb.getStepId(), "0", DateUtils.getNowDate(), gwjSceneExpendSubmitRequest.getContent(), sysUser);
        return true;
    }

    /**
     * 处理修改的项目和楼栋信息
     * 
     * @param bizId
     * @param areaId
     * @param communityId
     * @param buildCodes
     */
    private void processEditBasicHouse(Long bizId, Long areaId, Long communityId, String[] buildCodes, SysUser sysUser) {
        // 根据bizId查项目id
        GwjSceneExpendBusinessCommunity gsebc = iGwjSceneExpendBusinessCommunityService.selectGwjSceneExpendBusinessCommunityByBizId(bizId);
        if (StringUtils.isNull(gsebc)) {
            throw new ServiceException("未获取到对应业务下的项目信息！");
        }
        // 不管是否重复都删除后重新新增
        // 删除业主跟房屋信息
        // 删除业主信息
        iGwjSceneExpendBusinessOwnerService.deleteGwjSceneExpendBusinessOwnerByBizId(bizId);
        // 删除房屋信息
        iGwjSceneExpendBusinessHouseService.deleteGwjSceneExpendBusinessHouseByBizId(bizId);
        // 删除楼栋信息
        iGwjSceneExpendBusinessBuildService.deleteGwjSceneExpendBusinessBuildByBizId(bizId);
        // 删除项目信息
        iGwjSceneExpendBusinessCommunityService.deleteGwjSceneExpendBusinessCommunityByBizId(bizId);
        // 保存项目相关信息 s
        // 项目信息
        Long bizCommunityId = processSaveBusinessCommunity(bizId, communityId, sysUser);
        // 楼栋信息
        processSaveBusinessBuild(bizId, areaId, bizCommunityId, buildCodes, sysUser);
        // 新增房屋业主
        processSaveHouseAndOwnerByBuildCodes(bizId, areaId, buildCodes, sysUser);
        // e
    }

    /**
     * 批量处理坑爹版
     * 
     * @param list
     */
    private void batch(List<GwjSceneExpendBusinessHouse> list) {
        int totalSize = list.size();
        int num = 10;
        int pageSum = (totalSize - 1) / num + 1;

        for (int i = 1; i < pageSum; i++) {
            List<GwjSceneExpendBusinessHouse> topTenList = list.stream().limit(10).collect(Collectors.toList());
            // iGwjSceneExpendBusinessHouseService.upBatchGwjSceneExpendBusinessHouseByBaseHouse(topTenList);
            // 设置ExecutorType.BATCH原理：把SQL语句发个数据库，数据库预编译好，数据库等待需要运行的参数，接收到参数后一次运行，ExecutorType.BATCH只打印一次SQL语句，多次设置参数步骤
            SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
            try {
                // houseService.updateImportGwjBaseHouse(inHouseData);
                // for(int i=0;i<inHouseData.size();i++) {
                // inOwnerData.get(i).setHouseCode(inHouseData.get(i).getHouseCode());
                // }
                // ownerService.updateImportGwjBaseOwner(inOwnerData);
                iGwjSceneExpendBusinessHouseService.upBatchGwjSceneExpendBusinessHouseByBaseHouse(topTenList);
                session.commit();
            } catch (Exception e) {
                // throw new ServiceException("未获取到对于项目下的楼栋数据，请核对后再导入");
                e.printStackTrace();
            } finally {
                if (session != null) {
                    session.close();
                }
            }
            if (list.size() > num) {
                list = list.subList(num, list.size());
            }
        }
        if (list.size() > 0) {
            iGwjSceneExpendBusinessHouseService.upBatchGwjSceneExpendBusinessHouseByBaseHouse(list);
        }
    }

    /* 
     * 删除业务信息
     */
    @Override
    public boolean deleteBusiness(GwjSceneExpendSubmitRequest gwjSceneExpendSubmitRequest) {
        // 1查询业务状态
        Long bizId = gwjSceneExpendSubmitRequest.getBizId();
        GwjSceneExpendBusiness gseb = iGwjSceneExpendBusinessService.selectGwjSceneExpendBusinessByBizId(bizId);
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        String[] areaIds = SecurityUtils.getLoginUser().getAreaIds().split(",");
        checkGwjSceneExpendBusiness(gseb, sysUser, areaIds, null, false);
        // 变更状态
        GwjSceneExpendBusiness upGseb = new GwjSceneExpendBusiness();
        upGseb.setBizId(bizId);
        upGseb.setAreaId(gseb.getAreaId());
        upGseb.setUpdateTime(DateUtils.getNowDate());
        upGseb.setStatus(GwjBusinessStatus.INVALID.getCode());
        iGwjSceneExpendBusinessService.updateGwjSceneExpendBusinessByBizIdAndAreaId(upGseb);
        // 删除对应总账和分类账
        // 操作日志
        // 新增业务日志
        processSaveBusinessLog(bizId, gseb.getStepId(), "5", DateUtils.getNowDate(), gwjSceneExpendSubmitRequest.getContent(), sysUser);
        return true;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.forEach(s -> {
            throw new ServiceException("22222");
        });
    }

    /* 
     * 获取步骤配置信息
     */
    @Override
    public JSONObject stepInfo() {
        R<JSONObject> result = remoteGwjConfigService.selectGwjConfBusinessFlagInfoByBizFlagId(BusinessFlagEnum.SCENEEXPEND.getFlagId().intValue(), SecurityConstants.INNER);
        if (R.isError(result) || StringUtils.isNull(result.getData())) {
            throw new ServiceException("未获取到对应步骤配置信息，请联系管理员配置后再操作！");
        }
        return result.getData();
    }

    /*
     * 20230906
     *
     * 导入房屋列表
     */
    @Override
    public String importHouseList(MultipartFile file, boolean updateSupport, Long bizId) throws Exception {
        ExcelUtil<GwjSceneExpendBusinessHouseAndOwner> util = new ExcelUtil<GwjSceneExpendBusinessHouseAndOwner>(GwjSceneExpendBusinessHouseAndOwner.class);
        // 外网支出导入
        InputStream is = file.getInputStream();
        List<GwjSceneExpendBusinessHouseAndOwner> gwjSceneExpendBusinessHouseAndOwnerImpList = util.importExcel(is);
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        // 缓存更新组
        List<GwjSceneExpendBusinessHouse> upHouseData = new ArrayList<GwjSceneExpendBusinessHouse>();
        List<GwjSceneExpendBusinessOwner> upOwnerData = new ArrayList<GwjSceneExpendBusinessOwner>();
        // 临时计算标准(注：暂时以首位计算标准为准，之前人员表格设计时候，计算标准未与房屋做匹配操作，仅存放于整体info信息中，这里只做临时处理)
        // Integer calculationStandard = gwjSceneExpendBusinessHouseAndOwnerImpList.get(0).getCalculationStandard();
        for (GwjSceneExpendBusinessHouseAndOwner geobhao : gwjSceneExpendBusinessHouseAndOwnerImpList) {
            // 校验导入参数
            BeanValidators.validateWithException(validator, geobhao);
            // 房屋标识码
            String houseCode = geobhao.getHouseCode();
            if (StringUtils.isNull(houseCode)) {
                failureMsg.append(geobhao.getHouseLocation() + "[" + geobhao.getHouseCode() + "]" + "导入失败！房屋编号不能为空！");
                throw new ServiceException(failureMsg.toString());
            }
            // 查询当前房屋是否存在
            GwjSceneExpendBusinessHouse gmfbh = iGwjSceneExpendBusinessHouseService.selectGwjSceneExpendBusinessHouseByBizIdAndHouseCode(bizId, houseCode);
            if (StringUtils.isNull(gmfbh)) {
                failureMsg.append(geobhao.getHouseLocation() + "[" + houseCode + "]" + "导入失败！未获取到当前房屋信息！");
                // throw new ServiceException(failureMsg.toString());
                continue;
            }
            try {
                // 更新房屋信息
                GwjSceneExpendBusinessHouse uGsebh = new GwjSceneExpendBusinessHouse();
                // 业务ID
                uGsebh.setBizId(bizId);
                // 房屋标识码
                uGsebh.setHouseCode(houseCode);
                // 坐落
                uGsebh.setHouseLocation(geobhao.getHouseLocation());
                // 房号
                uGsebh.setRoomNum(geobhao.getRoomNum());
                // 缴款面积
                uGsebh.setDepositSize(geobhao.getDepositSize());
                // 规划用途
                uGsebh.setUseType(geobhao.getUseType());
                // 计算标准
                uGsebh.setCalculationStandard(geobhao.getCalculationStandard());
                // 应分摊金额
                uGsebh.setAllocationMoney(geobhao.getAllocationMoney());
                // 差额
                uGsebh.setLackMoney(geobhao.getLackMoney());
                // 实际分摊金额
                uGsebh.setActualAllocationMoney(geobhao.getActualAllocationMoney());
                // 自筹金额
                uGsebh.setSelfRaiseMoney(geobhao.getSelfRaiseMoney());
                // 本次分摊总金额
                uGsebh.setTotalAllocationMoney(geobhao.getTotalAllocationMoney());
                // 存储房屋更新组
                upHouseData.add(uGsebh);
                // 更新业主信息
                GwjSceneExpendBusinessOwner uGsebo = new GwjSceneExpendBusinessOwner();
                // 业务ID
                uGsebo.setBizId(bizId);
                // 房屋标识码
                uGsebo.setHouseCode(houseCode);
                // 业主姓名
                uGsebo.setOwnerName(geobhao.getOwnerName());
                // 业主身份证号
                uGsebo.setCardNum(geobhao.getCardNum());
                // 业主手机后
                uGsebo.setOwnerPhone(geobhao.getOwnerPhone());
                // 存储业主更新组
                upOwnerData.add(uGsebo);
                // 修改操作
                if (upHouseData.size() == 100 && upOwnerData.size() == 100) {
                    // 调用更新组
                    upImportHouseAndOwner(upHouseData, upOwnerData);
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、房屋编号： " + houseCode + ",房屋和业主数据导入失败：";
                log.error(msg, e);
            }
        }
        // 对余留数据进行修改
        if (upHouseData.size() > 0 && upOwnerData.size() > 0) {
            // 调用更新组
            upImportHouseAndOwner(upHouseData, upOwnerData);
        }

        if (failureNum > 0) {
            throw new ServiceException("很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确");
        } else {
            // successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
            successMsg.insert(0, "恭喜您，数据已全部导入成功！");
        }
        if (is != null) {
            is.close();
        }
        return successMsg.toString();
    }

    /**
     * 修改导入的房屋和业主
     *
     * @param inHouseData
     * @param inOwnerData
     */
    private void upImportHouseAndOwner(List<GwjSceneExpendBusinessHouse> inHouseData, List<GwjSceneExpendBusinessOwner> inOwnerData) {
        if ((StringUtils.isNull(inHouseData) && inHouseData.size() == 0) || (StringUtils.isNull(inOwnerData) && inOwnerData.size() == 0)) {
            return;
        }
        // 设置ExecutorType.BATCH原理：把SQL语句发个数据库，数据库预编译好，数据库等待需要运行的参数，接收到参数后一次运行，ExecutorType.BATCH只打印一次SQL语句，多次设置参数步骤
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
        try {
            iGwjSceneExpendBusinessHouseService.upBatchGwjSceneExpendBusinessHouseByBaseHouse(inHouseData);
            // for(int i=0;i<inHouseData.size();i++) {
            // inOwnerData.get(i).setHouseCode(inHouseData.get(i).getHouseCode());
            // }
            iGwjSceneExpendBusinessOwnerService.updateBatchGwjSceneExpendBusinessOwner(inOwnerData);
            session.commit();
        } catch (Exception e) {
            // throw new ServiceException("未获取到对于项目下的楼栋数据，请核对后再导入");
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    /* 
     * 业务房屋导出
     */
    @Override
    public List<GwjSceneExpendBusinessHouseAndOwner> exportHouseList(GwjSceneExpendHouseAndOwnerRequest gwjSceneExpendHouseAndOwnerRequest) {
        return iGwjSceneExpendBusinessHouseService.selectGwjSceneExpendBusinessHousesAndOwners(gwjSceneExpendHouseAndOwnerRequest.getBizId(), gwjSceneExpendHouseAndOwnerRequest.getAreaId(), "1");
    }

}
